﻿using Newtonsoft.Json.Linq;
using System;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using ZLDocEditorEvents.Comm;
using ZLSoft.DocManage;
using ZLSoft.DocManage.Core.LocalService.ModuleService;
using ZLSoft.ZLDocEditorEvents.Comm;

namespace ZLSoft.ZLDocEditorEvents {
    public class EventProcess {
        private IntPtr Phandle;

        private string ZlemrCode = "ZLDOC.MAIN";//病历库数据源code

        private string HisCode = "ZLDOC.MAIN002";//His库数据源code

        private IEventService service;
        //private clsPlugInExtent clsPlug;
        public EventProcess() {
            DocStationLogic.EditorDeseaseConfirm += this.ImportClinicalPathway;
            DocStationLogic.OnGetSelectText += this.DocStationLogic_OnGetSelectText;
            DocStationLogic.OnBeforeDocSave += this.DocStationLogic_OnBeforeDocSave;
            this.service = DocStationLogic.eventService;
            Init.InitParameter();
            //初始化三方参数
            IniServerPara();
            Init.UserName = GetUserName();
            Init.UserInfo = GetUserInfo();
            if (string.IsNullOrEmpty(Init.UserInfo)) {
                return;
            }
            Func.WriteBusinessLog("初始化VTE事件接口");
        }


        /// <summary>
        /// 点击保存或签名时，保存事务之前        根据事件返回决定是否可以继续保存
        /// </summary>
        /// <param name="patientId">病人ID</param>
        /// <param name="pageId">主页ID/挂号ID</param>
        /// <param name="antetypeId">原型ID</param>
        /// <param name="docTitle">病历标题</param>
        /// <param name="docContentText">病历内容text</param>
        /// <param name="cancel"></param>
		private void DocStationLogic_OnBeforeDocSave(string patientId, string pageId, string antetypeId, string docTitle, string docContentText, ref bool cancel) {
            int iType = 0;
            if (pageId.Length > 2) {
                iType = 1;
            } else {
                iType = 2;
            }

            try {
                Func.WriteBusinessLog("调用VTE事件接口，传入的病历标题为：" + docTitle);
                JObject jobj = new JObject();
                jobj["funcode"] = "ControlMeasures";
                jobj["productcode"] = "hisqqfvte"; //系统名– 对接前规定
                jobj["orgid"] = "syqy"; //机构代码
                string pat = GetPatientInfo(patientId, pageId, iType); //就诊号
                if (string.IsNullOrEmpty(pat)) {
                    return;
                }
                jobj["serialNo"] = pat;
                string intType = "";
                if (string.IsNullOrEmpty(GetMoment(antetypeId))) {
                    return;
                } else {
                    intType = GetMoment(antetypeId);
                }
                jobj["moment"] = intType;
                jobj["assessType"] = 1;
                jobj["appId"] = "his";
                Func.WriteBusinessLog("调用VTE卡控服务，卡控地址：" + Init.ServerUrl);
                Func.WriteBusinessLog("调用VTE卡控服务，入参：" + jobj.ToString());
                // 在调用该方法之后
                string responseString = HttpFun.httpPost(Init.ServerUrl, jobj.ToString(), null, "POST");

                // 解析JSON字符串
                JObject jReturn = JObject.Parse(responseString);
                //JObject jReturn = JObject.Parse(HttpFun.httpPost(Init.ServerUrl, jobj.ToString(), null));
                Func.WriteBusinessLog("调用VTE卡控服务，出参：" + jReturn.ToString());
                if (Func.Nvl(jReturn["code"]).Equals("200")) {
                    if (Func.Nvl(jReturn["data"]["assessFlag"]).Equals("2")) {
                        MessageBox.Show("还未进行VTE评估，请先评估后再保存病历。", "VTE卡控平台", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        //唤醒卡控系统
                        string param = $"doctorId={Input.DoctorId}&doctorName={Init.UserName}&orgCode={Input.OrgCode}" +
                            $"&deptCode={Input.DeptCode}&wardCode={Input.WardCode}&userType={Input.UserType}&admsnNo={pat}&moment={intType}&assessType=1"
                            + "&platform=VTE&appCode=vteApp";

                        Init.gstrSql = "select A.参数名,A.参数值 from 三方接口配置 A where 接口名='科大讯飞VTE自动调用客户端地址'";
                        DataTable dt = this.ExcuteTable(this.HisCode, CommandType.Text, Init.gstrSql, null);
                        if (dt != null) {
                            Init.ExeFullPath = dt.Rows[0]["参数值"].ToString();
                        }
                        //Init.ExeFullPath = @"C:\Program Files\ZLSoft\ishell\iShell.exe";
                        Func.WriteBusinessLog("调用VTE卡控程序，程序路径：" + Init.ExeFullPath);
                        Func.WriteBusinessLog("调用VTE卡控程序，入参：" + param);
                        if (File.Exists(Init.ExeFullPath)) {
                            Process process = new Process();
                            ProcessStartInfo startInfo = new ProcessStartInfo(Init.ExeFullPath, param);
                            process.StartInfo = startInfo;
                            process.Start();
                        }
                        cancel = true;
                        return;
                    }
                } else {
                    MessageBox.Show(Func.Nvl(jReturn["message"]), "VTE卡控平台", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    cancel = true;
                    return;
                }
            } catch (Exception ex) {
                MessageBox.Show(ex.Message);
            }
        }
        private string GetMoment(string intType) {
            Init.gstrSql = "select A.DOC_KIND,A.TITLE from Antetype_List@Zlemr A where  A.ID='" + intType + "'";
            Func.WriteBusinessLog("获取评估时机信息：" + Init.gstrSql);
            DataTable dt = this.ExcuteTable(this.HisCode, CommandType.Text, Init.gstrSql, null);
            switch (dt.Rows[0]["TITLE"].ToString()) {
                case "通用入院记录(中西)":
                    return "1";
                case "24小时内入院死亡记录":
                    return "1";
                case "24小时内入出院记录":
                    return "1";
                case "通用入院记录(西)":
                    return "1";
                case "出院记录":
                    return "6";
                case "死亡记录":
                    return "6";
                    //case "手术同意书":
                    //    return "4";
                    //case "术后首次病程记录":
                    //    return "5";
                    //case "出院小结":
                    //    return "6";
                    //case "转科记录":
                    //    if (dt.Rows[0]["DOC_KIND"].ToString().Trim() == "转入记录") {
                    //        return "3";
                    //    } else {
                    //        return "2";
                    //    }
            }
            return "";
        }

        /// <summary>
        /// 获取选中文本事件响应
        /// </summary>
        /// <param name="x">鼠标位置x轴</param>
        /// <param name="y">鼠标位置y轴</param>
        /// <param name="mouseButton">鼠标按键，0-左键；1-右键；2-滚动键</param>
        /// <param name="key">键盘按键,0-None；1-Shift；2-Ctrl；4-Alt</param>
        /// <param name="selectText">选中文本</param>
		private void DocStationLogic_OnGetSelectText(int x, int y, int mouseButton, int key, string selectText) {
            //
        }

        /// <summary>
        /// 导入临床路径
        /// </summary>
        /// <param name="masterID">病人id</param>
        /// <param name="mainPageID">主页id</param>
        private void ImportClinicalPathway(IntPtr pHandle, string masterID, string mainPageID) {
            if (this.service != null) {
                object hisConn = this.service.GetHisConn();
                this.Phandle = pHandle;
                if (hisConn != null) {
                    try {
                        Type typeFromProgID = Type.GetTypeFromProgID("zlPublicPath.clsPublicPath");
                        if (typeFromProgID != null) {
                            object obj = Activator.CreateInstance(typeFromProgID);
                            obj.GetType().InvokeMember("zlImportInPathForEMR", BindingFlags.InvokeMethod, null, obj, new object[]
                            {
                                hisConn,
                                this.Phandle.ToInt32(),
                                masterID,
                                mainPageID
                            });
                        }
                    } catch (Exception ex) {
                        if (!ex.Message.Contains("未知名称")) {
                            throw ex;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 执行sql语句
        /// </summary>
        /// <param name="extentedSourceCode">病历扩展数据源code,即extend_sources表中code字段的值</param>
        /// <param name="commandType">执行sql的类型，Text为sql文本，StoredProcedure为存储过程</param>
        /// <param name="commandText">sql内容</param>
        /// <param name="parameters">sql参数</param>
        /// <returns></returns>
        private DataTable ExcuteTable(string extentedSourceCode, CommandType commandType, string commandText, SqlParamInfo[] parameters) {
            if (this.service != null) {
                return this.service.ExcuteTable(extentedSourceCode, commandType, commandText, parameters);
            }
            return null;
        }

        private string GetUserName() {
            object[] para;
            string strReturn = "";
            try {
                Type typeReport = Type.GetTypeFromProgID("zlRegister.clsRegister");
                if (typeReport != null) {
                    object obj = Activator.CreateInstance(typeReport);
                    Type typLis = obj.GetType();
                    string strMsg = null;
                    para = new object[] { 0, strMsg };
                    ADODB.Connection conn = (ADODB.Connection)typLis.InvokeMember("ReGetConnection", BindingFlags.InvokeMethod, null, obj, para);
                    string[] str = conn.ConnectionString.Split(';');
                    for (int i = 0; i < str.Length; i++) {
                        if (str[i].ToUpper().StartsWith("USER ID")) {
                            strReturn = (str[i].Split('=')[1]).ToUpper();
                        }
                    }
                    Func.WriteBusinessLog("获取登录账号：" + strReturn);
                }
            } catch (Exception ex) {

            }
            return strReturn;
        }

        /// <summary>
        /// 查询his库数据例子,sql文本
        /// </summary>
        private void GetHisInfoSample() {
            this.ExcuteTable(this.HisCode, CommandType.Text, "select Sysdate from dual", null);
        }

        /// <summary>
        /// 查询emr库数据例子,存储过程
        /// </summary>
        private void GetEmrInfoSample() {
            //sqlParam参数的构成以游标类型为例，第一个参数为参数名，第二个为参数类型，第三个参数值，第四个是否游标，第五个参数方向,其他参数参照方法
            SqlParamInfo[] sqlTempparam = new SqlParamInfo[] { new SqlParamInfo("Val", DbType.Object, null, true, ParameterDirection.Output) };
            //第一次参数传入的为已定义的emr数据源code
            DataTable dt = ExcuteTable(ZlemrCode, CommandType.StoredProcedure, "b_Doc_Base.p_Get_Doc_Kind", sqlTempparam);
        }

        /// <summary>
        /// 获取登陆用户信息
        /// </summary>
        /// <returns></returns>
        private string GetUserInfo() {
            string str用户信息 = "";
            try {
                //Decode(B.管理职务, '科室主任', '4', '1') As 用户类型
                Init.gstrSql = @"select B.ID As 医生ID,B.姓名 As 医生姓名, CASE 
                                    WHEN B.编号 LIKE 'D%' THEN '1'
                                    WHEN B.编号 LIKE 'N%' THEN '2'
                                    ELSE '0'
                                END AS 用户类型,A.用户名 from 上机人员表 A,人员表 B where A.人员ID=B.ID And A.用户名='" + Init.UserName + "'";
                Func.WriteBusinessLog("获取登录信息：" + Init.gstrSql);
                DataTable dt = this.ExcuteTable(this.HisCode, CommandType.Text, Init.gstrSql, null);
                Input.DoctorId = Init.UserName;
                if (dt.Rows.Count > 0) {
                    if (dt.Rows[0]["用户类型"].ToString() == "0") {
                        return "";
                    }
                    Input.DoctorName = dt.Rows[0]["用户名"].ToString();
                    str用户信息 = dt.Rows[0]["用户类型"].ToString() + "|" + dt.Rows[0]["医生ID"].ToString() + "|" + dt.Rows[0]["医生姓名"].ToString() + "|" + dt.Rows[0]["用户名"].ToString();
                    Input.UserType = dt.Rows[0]["用户类型"].ToString();
                }
            } catch (Exception ex) {
                throw;
            }
            return str用户信息;
        }
        /// <summary>
        /// 获取VTE自动拉起地址
        /// </summary>
        /// <returns></returns>
        private string GetVteAddress() {
            string vteAddress = "";
            try {
                string gstrSql = "select A.参数值 from 三方接口配置 A where A.接口名 = '科大讯飞VTE自动调用客户端地址'";
                Func.WriteBusinessLog("科大讯飞VTE自动调用客户端地址：" + gstrSql);
                DataTable dt = this.ExcuteTable(this.HisCode, CommandType.Text, gstrSql, null);
                Func.WriteBusinessLog("科大讯飞VTE自动调用客户端地址成功");
                vteAddress = dt.Rows[0]["参数值"].ToString();
            } catch (Exception ex) {
                throw;
            }
            return vteAddress;
        }

        /// <summary>
        /// 获取服务地址
        /// </summary>
        /// <returns></returns>
        private bool IniServerPara() {
            bool blnState = false;
            try {
                Init.gstrSql = "select A.参数名,A.参数值 from 三方接口配置 A where 接口名='VTE_科大讯飞'";
                DataTable dt = this.ExcuteTable(this.HisCode, CommandType.Text, Init.gstrSql, null);
                if (dt != null) {
                    foreach (object obj in dt.Rows) {
                        DataRow dataRow = (DataRow)obj;
                        string paraName = dataRow["参数名"].ToString();
                        switch (paraName) {
                            case "卡控地址":
                                Init.ServerUrl = Func.Nvl(dataRow["参数值"]);
                                break;
                                //case "机构代码":
                                //    Init.OrgCode = Func.Nvl(dataRow["参数值"]);
                                //    break;
                                //case "系统名称":
                                //    Init.ProductCode = Func.Nvl(dataRow["参数值"]);
                                //    break;
                                //case "VTE程序名":
                                //    Init.ExeName = Func.Nvl(dataRow["参数值"]);
                                //    break;
                                //case "VTE事件":
                                //    Init.DocConvert = Func.Nvl(dataRow["参数值"]);
                                //    break;
                                //case "病历事件":
                                //    Init.EventConvert = Func.Nvl(dataRow["参数值"]);
                                //    break;
                                //case "数据库连接":
                                //    Init.Conn = Init.Decrypt(Func.Nvl(dataRow["参数值"]));
                                //    break;
                                //case "调用卡控":
                                //    Init.CallVte = Func.Nvl(dataRow["参数值"]);
                                //    break;
                        }
                    }
                }
                string path = Init.GetExePath(Init.ExeName);
                if (!string.IsNullOrWhiteSpace(path)) Init.ExeFullPath = Path.Combine(path, Init.ExeName);
                blnState = true;
            } catch (Exception ex) {
                throw;
            }
            return blnState;
        }

        /// <summary>
        /// 获取当前患者信息
        /// </summary>
        /// <param name="iType">1-门诊 2-住院</param>
        /// <param name="lngPatientId">病人ID</param>
        /// <param name="lngPageId">主页ID</param>
        /// <returns></returns>
        private string GetPatientInfo(string lngPatientId, string lngPageId, int iType) {
            string str标识号 = "";
            try {
                if (iType == 1) {
                    return "";
                    //Init.gstrSql = "Select A.门诊号 As 标识号, A.ID As 就诊ID, B.ID As 科室代码, B.ID As 病区代码\n" +
                    //    "From 病人挂号记录 A, 部门表 B\n" +
                    //    "Where A.执行部门ID = B.ID And A.病人ID = '" + lngPatientId + "' And A.ID = '" + lngPageId + "'";
                    //DataTable dt = this.ExcuteTable(this.HisCode, CommandType.Text, Init.gstrSql, null);
                    //if (dt.Rows.Count > 0) {
                    //    Input.DeptCode = dt.Rows[0]["科室代码"].ToString();
                    //    Input.WardCode = dt.Rows[0]["病区代码"].ToString();
                    //    Input.OrgCode = "iflytek";
                    //    Input.AdmsnNo = dt.Rows[0]["就诊ID"].ToString();
                    //}
                } else {
                    Init.gstrSql = "Select A.住院号 As 标识号, A.主页ID As 就诊ID, (Select ID From 部门表 Where ID = A.出院科室ID) As 科室代码, (Select ID From 部门表 Where ID = A.当前病区ID) As 病区代码\n" +
                        "From 病案主页 A\n" +
                        "Where A.病人ID = '" + lngPatientId + "' And A.主页ID = '" + lngPageId + "'";
                    DataTable dt = this.ExcuteTable(this.HisCode, CommandType.Text, Init.gstrSql, null);
                    if (dt.Rows.Count > 0) {
                        Input.DeptCode = dt.Rows[0]["科室代码"].ToString();
                        Input.WardCode = dt.Rows[0]["病区代码"].ToString();
                        Input.OrgCode = "iflytek";
                        Input.AdmsnNo = lngPatientId + "_" + dt.Rows[0]["就诊ID"].ToString();
                    }
                }
            } catch (Exception ex) {
                throw;
            }
            return Input.AdmsnNo;
        }

        /// <summary>
        /// 验证是否启用接口
        /// </summary>
        /// <param name="iType">1-门诊 2-住院</param>
        /// <param name="lngPatientId">病人ID</param>
        /// <param name="lngPageId">主页ID</param>
        /// <returns></returns>
        private bool CheckDepartmentId(string lngPatientId, string lngPageId, int iType) {
            string strSql = "";
            bool blnState = false;
            try {
                if (iType == 1) {
                    strSql = "select count(*) As 数量" +
                        "  from 病人挂号记录 A, 插件适用科室 B" +
                        " where A.病人ID = '" + lngPatientId + "'" +
                        "   And A.ID = '" + lngPageId + "'" +
                        "   And A.执行部门ID = B.科室ID" +
                        "   And B.是否使用 = 1 And B.类型=3";
                } else {
                    strSql = "select count(*) As 数量 from 病案主页 A, 插件适用科室 B where A.病人ID='" + lngPatientId + "' And A.主页ID='" + lngPageId + "' And A.出院科室ID=B.科室ID And B.是否使用 = 1 And B.类型=3";
                }

                DataTable dt = this.ExcuteTable(this.HisCode, CommandType.Text, strSql, null);
                if (dt.Rows.Count > 0) {
                    blnState = (Convert.ToInt32(dt.Rows[0]["数量"]) >= 1);
                }
            } catch (Exception ex) {
                throw;
            }
            return blnState;
        }
    }
}
